home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * *
- * Palette Requester *
- * *
- * (c) Copyright 1989 Jonathan Potter *
- * *
- * This program is freely redistributable, although all rights to it remain *
- * with the author. It may be used freely in any program as long as this *
- * notice remains intact, however, if you do this, please mention the *
- * author in the program. If you wish to use this in a commercial program *
- * of any kind, you must register with a $15 donation. *
- * Please send donations, bug reports, comments and suggestions to : *
- * *
- * Jonathan Potter *
- * 3 William Street *
- * Clarence Park 5034 *
- * South Australia *
- * Australia *
- * *
- * Ph : (08) 2932788 home *
- * *
- ****************************************************************************/
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/screens.h>
- #include <libraries/dosextens.h>
- #include <graphics/gfxbase.h>
- #ifdef __SASC
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #endif
- #include "PaletteReq.h"
-
- #define RED 32
- #define BLUE 33
- #define GREEN 34
- #define CRESET 35
- #define CCANCEL 36
- #define COK 37
- #define USER 38
- #define SPREAD 39
- #define COPY 40
- #define HUE 41
- #define SAT 42
- #define LUM 43
-
- #define INITREG(n) (GetRGB4(cvp->ColorMap,n))
- #define REDREG(n) ((n>>8)&0xf)
- #define GREENREG(n) ((n>>4)&0xf)
- #define BLUEREG(n) (n&0xf)
-
- static int redtable[32], greentable[32], bluetable[32];
- static char values[4];
-
- static struct IntuiText
- coktext={1,0,JAM1,41,1,NULL,(UBYTE *)"OKAY",NULL},
- canceltext={1,0,JAM1,33,1,NULL,(UBYTE *)"CANCEL",NULL},
- usertext={1,0,JAM1,0,1,NULL,(UBYTE *)"",NULL},
- resettext={1,0,JAM1,37,1,NULL,(UBYTE *)"RESET",NULL},
- spreadtext={1,0,JAM1,33,1,NULL,(UBYTE *)"SPREAD",NULL},
- copytext={1,0,JAM1,41,1,NULL,(UBYTE *)"COPY",NULL},
- RText={1,0,JAM1,-15,1,NULL,"R",NULL},
- GText={1,0,JAM1,-15,1,NULL,"G",NULL},
- BText={1,0,JAM1,-15,1,NULL,"B",NULL},
- HText={1,0,JAM1,106,1,NULL,"H",NULL},
- SText={1,0,JAM1,106,1,NULL,"S",NULL},
- LText={1,0,JAM1,106,1,NULL,"L",NULL},
- valstext={0,1,JAM2,0,0,NULL,values,NULL};
-
- static short border1_xy[]={
- 0,0,115,0,115,10,0,10,0,0};
- static struct Border border1={
- -1,-1,1,0,JAM1,5,border1_xy,NULL};
- static short border2_xy[]={
- 0,0,239,0,239,10,0,10,0,0};
- static struct Border border2={
- -1,-1,1,0,JAM1,5,border2_xy,NULL};
-
- static struct PropInfo
- RProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
- GProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
- BProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
- HProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
- SProp={AUTOKNOB|FREEHORIZ,0,0,1<<12},
- LProp={AUTOKNOB|FREEHORIZ,0,0,1<<12};
-
- static struct Image RImage, GImage, BImage, HImage, SImage, LImage,
- WCol={0,0,235,8,1,NULL,0,1,NULL};
-
- static struct Gadget
- cokgadget={
- NULL,9,118,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,&coktext,NULL,NULL,COK,NULL},
- cancelgadget={
- &cokgadget,133,118,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,&canceltext,NULL,NULL,CCANCEL,NULL},
- usergadget={
- &cancelgadget,133,105,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,&usertext,NULL,NULL,USER,NULL},
- resetgadget={
- &usergadget,9,105,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,&resettext,NULL,NULL,CRESET,NULL},
- spreadgadget={
- &resetgadget,133,92,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,&spreadtext,NULL,NULL,SPREAD,NULL},
- copygadget={
- &spreadgadget,9,92,114,9,GADGHCOMP,RELVERIFY,BOOLGADGET,
- (APTR)&border1,NULL,©text,NULL,NULL,COPY,NULL},
- Lum={
- ©gadget,132,79,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&LImage,NULL,<ext,NULL,(APTR)&LProp,LUM,NULL},
- Sat={
- &Lum,132,67,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&SImage,NULL,&SText,NULL,(APTR)&SProp,SAT,NULL},
- Hue={
- &Sat,132,55,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&HImage,NULL,&HText,NULL,(APTR)&HProp,HUE,NULL},
- Red={
- &Hue,24,55,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&RImage,NULL,&RText,NULL,(APTR)&RProp,RED,NULL},
- Green={
- &Red,24,67,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&GImage,NULL,>ext,NULL,(APTR)&GProp,GREEN,NULL},
- Blue={
- &Green,24,79,100,10,GADGHNONE|GADGIMAGE,RELVERIFY|GADGIMMEDIATE,PROPGADGET,
- (APTR)&BImage,NULL,&BText,NULL,(APTR)&BProp,BLUE,NULL};
-
- static struct NewWindow colwin={
- 40,23,255,131,0,1,CLOSEWINDOW|GADGETUP|GADGETDOWN|MOUSEBUTTONS|RAWKEY,
- WINDOWDRAG|WINDOWCLOSE|ACTIVATE|SMART_REFRESH|RMBTRAP,
- &Blue,NULL,"Palette",NULL,NULL,0,0,0,0,CUSTOMSCREEN};
-
- static struct Window *PWindow;
- static struct IntuiMessage *PMsg;
- static struct ViewPort *cvp;
- extern struct IntuitionBase *IntuitionBase;
- extern struct GfxBase *GfxBase;
- static ULONG colb;
-
- palette_request(win,winx,winy,hail,user,depth)
- struct Window *win;
- int winx, winy;
- char *hail;
- char *user;
- int depth;
- {
- int col,reg,i,Class,Code,GadgetID,x,y,last,first,sw,sh;
- if (!IntuitionBase) return(NO_INTUITION);
- if (!GfxBase) return(NO_GRAPHICS);
- if (!win) { colwin.Type=WBENCHSCREEN; sw=640; sh=200; }
- else {
- colwin.Screen=win->WScreen;
- sw=win->WScreen->Width; sh=win->WScreen->Height;
- }
- if (hail) colwin.Title=hail;
- if (user) {
- if (strlen(user)>14) user[14]='\0';
- usertext.IText=user;
- usertext.LeftEdge=(115-(strlen(user)*8))/2;
- }
- else {
- resetgadget.NextGadget=&cancelgadget;
- resetgadget.Width=238;
- resetgadget.GadgetRender=(APTR)&border2;
- resettext.LeftEdge=99;
- }
- if (winx>-1) {
- colwin.LeftEdge=winx;
- if (winx+255>sw)
- colwin.LeftEdge=sw-255;
- }
- if (winy>-1) {
- colwin.TopEdge=winy;
- if (winy+131>sh)
- colwin.TopEdge=sh-131;
- }
- PWindow=(struct Window *) OpenWindow(&colwin);
- if (!PWindow) return(OPENWINDOW_FAILED);
- cvp=&(PWindow->WScreen->ViewPort);
- if (!depth) depth=2;
- if (depth<1) depth=1; if (depth>5) depth=5;
- drawersquares(depth);
-
- InitTable(depth);
- col=1; WCol.PlaneOnOff=col;
- valstext.FrontPen=col^(power(2,depth)-1); valstext.BackPen=1;
- DrawImage(PWindow->RPort,&WCol,10,45);
- PosPots(depth,col);
- PosHSLPots(depth,col);
- FOREVER {
- Wait(1<<PWindow->UserPort->mp_SigBit);
- while (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
- Class=PMsg->Class; Code=PMsg->Code;
- if (Class==GADGETUP || Class==GADGETDOWN)
- GadgetID=((struct Gadget *) PMsg->IAddress)->GadgetID;
- ReplyMsg((struct Message *) PMsg);
- switch (Class) {
- case CLOSEWINDOW:
- for (reg=0;reg<(power(2,depth));reg++)
- SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
- CloseWindow(PWindow);
- return(FALSE);
- break;
- case MOUSEBUTTONS:
- if (Code!=SELECTDOWN) break;
- x=PWindow->MouseX; y=PWindow->MouseY;
- if (x<12 || x>243 || y<15 || y>40) break;
- if (col==ReadPixel(PWindow->RPort,x,y)) break;
- col=ReadPixel(PWindow->RPort,x,y);
- WCol.PlaneOnOff=col;
- DrawImage(PWindow->RPort,&WCol,10,45);
- PosPots(depth,col);
- PosHSLPots(depth,col);
- break;
- case GADGETDOWN:
- switch (GadgetID) {
- case RED:
- case GREEN:
- case BLUE:
- SetCols(depth,col);
- while (!(PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)))
- SetCols(depth,col);
- ReplyMsg((struct Message *) PMsg);
- SetCols(depth,col);
- break;
- case HUE:
- case SAT:
- case LUM:
- SetHSLCols(depth,col);
- while (!(PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)))
- SetHSLCols(depth,col);
- ReplyMsg((struct Message *) PMsg);
- SetHSLCols(depth,col);
- break;
-
- }
- break;
- case RAWKEY:
- if (Code!=0x45) break;
- GadgetID=CRESET; Class=GADGETUP;
- case GADGETUP:
- switch (GadgetID) {
- case CRESET:
- for (reg=0;reg<(power(2,depth));reg++) {
- SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
- if (reg==col) {
- PosPots(depth,col);
- PosHSLPots(depth,col);
- }
- }
- break;
- case USER:
- if (!user) break;
- CloseWindow(PWindow);
- return(5);
- case COK:
- CloseWindow(PWindow);
- return(TRUE);
- case CCANCEL:
- for (reg=0;reg<(power(2,depth));reg++)
- SetRGB4(cvp,reg,redtable[reg],greentable[reg],bluetable[reg]);
- CloseWindow(PWindow);
- return(FALSE);
- case COPY:
- FOREVER {
- Wait(1<<PWindow->UserPort->mp_SigBit);
- if (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
- Class=PMsg->Class; Code=PMsg->Code;
- ReplyMsg((struct Message *) PMsg);
- if (Class!=MOUSEBUTTONS && Code!=SELECTDOWN) continue;
- x=PWindow->MouseX; y=PWindow->MouseY;
- if (x<12 || x>243 || y<15 || y>40) continue;
- GadgetID=ReadPixel(PWindow->RPort,x,y);
- if (GadgetID>-1 && GadgetID<32) break;
- }
- }
- colb=INITREG(col);
- SetRGB4(cvp,GadgetID,REDREG(colb),GREENREG(colb),BLUEREG(colb));
- col=GadgetID;
- WCol.PlaneOnOff=col;
- DrawImage(PWindow->RPort,&WCol,10,45);
- PosPots(depth,col);
- PosHSLPots(depth,col);
- case SPREAD:
- FOREVER {
- Wait(1<<PWindow->UserPort->mp_SigBit);
- if (PMsg=(struct IntuiMessage *) GetMsg(PWindow->UserPort)) {
- Class=PMsg->Class; Code=PMsg->Code;
- ReplyMsg((struct Message *) PMsg);
- if (Class!=MOUSEBUTTONS && Code!=SELECTDOWN) continue;
- x=PWindow->MouseX; y=PWindow->MouseY;
- if (x<12 || x>243 || y<15 || y>40) continue;
- GadgetID=ReadPixel(PWindow->RPort,x,y);
- if (GadgetID>-1 && GadgetID<32) break;
- }
- }
- first=col; last=GadgetID;
- if (first>last) {
- i=first; first=last; last=i;
- }
- if (first>=last-1) break;
- dospread(first,last);
- col=GadgetID;
- WCol.PlaneOnOff=col;
- DrawImage(PWindow->RPort,&WCol,10,45);
- PosPots(depth,col);
- PosHSLPots(depth,col);
- break;
- default:
- break;
- }
- }
- }
- }
- }
-
- static PosPots(depth,col)
- int depth,col;
- {
- ULONG hpr,hpg,hpb;
- colb=INITREG(col);
- hpr=REDREG(colb)*0x1111;
- hpg=GREENREG(colb)*0x1111;
- hpb=BLUEREG(colb)*0x1111;
- if (RProp.HorizPot==hpr && GProp.HorizPot==hpg && BProp.HorizPot==hpb)
- return(0);
- NewModifyProp(&Red,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpr,0,1<<12,0,1);
- NewModifyProp(&Green,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpg,0,1<<12,0,1);
- NewModifyProp(&Blue,PWindow,NULL,FREEHORIZ|AUTOKNOB,hpb,0,1<<12,0,1);
- ShowVals(depth,REDREG(colb),GREENREG(colb),BLUEREG(colb),col);
- return(0);
- }
-
- static PosHSLPots(depth,col)
- int depth, col;
- {
- colb=INITREG(col);
- RGBToHSL(colb,&HProp.HorizPot,&SProp.HorizPot,&LProp.HorizPot);
- NewModifyProp(&Hue,PWindow,NULL,FREEHORIZ|AUTOKNOB,HProp.HorizPot,0,1<<12,0,1);
- NewModifyProp(&Sat,PWindow,NULL,FREEHORIZ|AUTOKNOB,SProp.HorizPot,0,1<<12,0,1);
- NewModifyProp(&Lum,PWindow,NULL,FREEHORIZ|AUTOKNOB,LProp.HorizPot,0,1<<12,0,1);
- return(0);
- }
-
- static SetHSLCols(depth,col)
- int depth,col;
- {
- ULONG rgb, red, green, blue;
- rgb=(ULONG) HSLToRGB(HProp.HorizPot,SProp.HorizPot,LProp.HorizPot);
- red=rgb>>8; green=rgb>>4; blue=rgb;
- SetRGB4(cvp,col,red,green,blue);
- PosPots(depth,col);
- return(0);
- }
-
- static SetCols(depth,col)
- int depth;
- int col;
- {
- USHORT re,gr,bl;
- re=RProp.HorizPot/0x1111;
- gr=GProp.HorizPot/0x1111;
- bl=BProp.HorizPot/0x1111;
- colb=INITREG(col);
- if (re==REDREG(colb) && gr==GREENREG(colb) && bl==BLUEREG(colb)) return(0);
- SetRGB4(cvp,col,re,gr,bl);
- ShowVals(depth,re,gr,bl,col);
- PosHSLPots(depth,col);
- return(0);
- }
-
- static InitTable(depth)
- int depth;
- {
- int reg;
- for (reg=0;reg<(power(2,depth));reg++) {
- colb=INITREG(reg);
- redtable[reg]=REDREG(colb);
- greentable[reg]=GREENREG(colb);
- bluetable[reg]=BLUEREG(colb);
- }
- return(0);
- }
-
- static ShowVals(depth,re,gr,bl,col)
- int depth,re,gr,bl,col;
- {
- values[0]=dostr(re);
- values[1]=dostr(gr);
- values[2]=dostr(bl);
- values[3]='\0';
- valstext.FrontPen=col^(power(2,depth)-1);
- valstext.BackPen=col;
- PrintIText(PWindow->RPort,&valstext,115,45);
- return(0);
- }
-
- static power(base,n)
- int base,n;
- {
- int p;
- for (p=1;n>0;--n) p*=base;
- return(p);
- }
-
- static drawersquares(depth)
- int depth;
- {
- int w,h,ox,x,y,i;
- w=235/(power(2,depth)); h=25; ox=12;
- if (depth==4) { w=29; h=12; ox=13; }
- if (depth==5) { w=14; h=12; ox=17; }
- i=0; x=ox; y=15;
- while (x<255 && y<45) {
- SetAPen(PWindow->RPort,i);
- RectFill(PWindow->RPort,x,y,x+w,y+h);
- ++i;
- x+=w;
- if (i>=power(2,depth)) break;
- if (depth>3 && i==(power(2,(depth-1)))) {
- x=ox; y+=h;
- }
- }
- return(0);
- }
-
- static dospread(first,last)
- int first,last;
- {
- int redst,greenst,bluest,red1,green1,blue1,red2,green2,blue2,
- redw,greenw,bluew,i;
- colb=INITREG(first);
- red1=REDREG(colb); green1=GREENREG(colb); blue1=BLUEREG(colb);
- colb=INITREG(last);
- red2=REDREG(colb); green2=GREENREG(colb); blue2=BLUEREG(colb);
- redst=((red2-red1)<<8)/(last-first);
- greenst=((green2-green1)<<8)/(last-first);
- bluest=((blue2-blue1)<<8)/(last-first);
- for (i=first+1;i<last;i++) {
- redw=red1+(((redst*(i-first))+128)>>8);
- greenw=green1+(((greenst*(i-first))+128)>>8);
- bluew=blue1+(((bluest*(i-first))+128)>>8);
- SetRGB4(cvp,i,redw,greenw,bluew);
- }
- return(0);
- }
-
- /* HSL <-> RGB routines
- adapted from the Amiga Programmers' Suite Book 1
- by Robert J. Mical
-
- ------------------------------------------------------------------------------
-
- * *** hsl.c ****************************************************************
- *
- * ColorWindow Routine -- HSL Translation Routines
- * from Book 1 of the Amiga Programmers' Suite by RJ Mical
- *
- * Copyright (C) 1986, 1987, Robert J. Mical
- * All Rights Reserved.
- *
- * Any or all of this code can be used in any program as long as this
- * entire copyright notice is retained, ok? Thanks.
- *
- * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
- * All copyright notices and all file headers must be retained intact.
- * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the
- * resultant object code may be included in any software product. However, no
- * portion of the source listings or documentation of the Amiga Programmer's
- * Suite Book 1 may be distributed or sold for profit or in a for-profit
- * product without the written authorization of the author, RJ Mical.
- *
- * HISTORY NAME DESCRIPTION
- * ----------- -------------- --------------------------------------------
- * 3 Jan 87 RJ >:-{)* Clean-up for release
- * 27 Feb 86 =RJ Mical= Modified these routines for Zaphod
- * January 86 =RJ= Modified the originals for Mandelbrot
- * Late 85 =RJ= Created the color window for Graphicraft
- *
- * *************************************************************************
-
- -----------------------------------------------------------------------------
-
- */
-
-
- static HSLToRGB(hue,sat,lum)
- USHORT hue, sat, lum;
- {
- ULONG red,green,blue,rdiff,gdiff,bdiff,foo,ris,fall,inv;
-
- foo=hue/0x2aab; ris=(hue-(foo*0x2aab))*6; fall=0xffff-ris;
- red=0xffff; green=0xffff; blue=0xffff;
- switch (foo) {
- case 0:
- green=ris; blue=0;
- break;
- case 1:
- red=fall; blue=0;
- break;
- case 2:
- red=0; blue=ris;
- break;
- case 3:
- red=0; green=fall;
- break;
- case 4:
- red=ris; green=0;
- break;
- case 5:
- green=0; blue=fall;
- break;
- }
-
- red=(red*lum)>>16; green=(green*lum)>>16; blue=(blue*lum)>>16;
- inv=0xffff-sat;
- rdiff=lum-red; red=red+((rdiff*inv)>>16);
- gdiff=lum-green; green=green+((gdiff*inv)>>16);
- bdiff=lum-blue; blue=blue+((bdiff*inv)>>16);
- red=(red>>12)&0xf; green=(green>>12)&0xf; blue=(blue>>12)&0xf;
- return((SHORT)((red<<8)|(green<<4)|(blue)));
- }
-
- static RGBToHSL(rgb,rhue,rsat,rlum)
- USHORT rgb;
- USHORT *rhue,*rsat,*rlum;
- {
- LONG min,max,hue,sat,lum,diff,rpart,gpart,bpart,rwork,gwork,bwork;
-
- rwork=((rgb>>8)&0xf)*0x111; gwork=((rgb>>4)&0xf)*0x111; bwork=(rgb&0xf)*0x111;
- if (rwork<gwork) min=rwork; else min=gwork; if (bwork<min) min=bwork;
- if (rwork>gwork) max=rwork; else max=gwork; if (bwork>max) max=bwork;
- lum=max; lum<<=4; diff=max-min;
- if (max) {
- sat=(diff<<16)/max; if (sat>0xffff) sat=0xffff;
- }
- else sat=0;
- if (sat==0) hue=0;
- else {
- rpart=(((max-rwork)<<16)/diff)>>4;
- gpart=(((max-gwork)<<16)/diff)>>4;
- bpart=(((max-bwork)<<16)/diff)>>4;
- if (rwork==max) hue=bpart-gpart;
- else if (gwork==max) hue=0x2000+rpart-bpart;
- else if (bwork==max) hue=0x4000+gpart-rpart;
- if (hue<0) hue+=0x6000; hue=(hue*2667)/1000;
- }
- *rhue=hue; *rsat=sat; *rlum=lum;
- return(0);
- }
-
- /*--------------------------------------------------------------------------*/
-
- dostr(val)
- int val;
- {
- if (val<10) return(val+48);
- return(val+87);
- }
-